#ifndef INPUT_MANAGER_H_
#define INPUT_MANAGER_H_

// Include the Windows API using Lean and Mean to exclude rarely
// used stuff from its headers
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

// Used for our dynamic array of listeners
#include <vector>


class InputListener;
class InputMessage;

class InputManager
{
	// Vector of classes that are listening to input
	std::vector<const InputListener*>	m_vListeners;
	unsigned char					m_rgucKeyBinds[256];

	// Used for checking keyboard input
	PBYTE							m_pByteKeys;
	PBYTE							m_pBytePrevKeys;

	// Handle to the window might be needed for some Windows functions
	HWND m_hWnd;

	InputManager(void);
	InputManager(const InputManager&){}
	InputManager& operator=(const InputManager&){}
	~InputManager(void){}

	// Calls HandleInput sending the message to all objects in the vector
	void SendMessage(const InputMessage * const pInputMsg);


public:
	// Singleton accessor
	static InputManager* GetInstance(void);

	// Initialize input devices and variables
	bool Initialize(HWND hWnd);

	// Process an input message from WinMain's MessageProc
	LRESULT CALLBACK ProcessMessage(unsigned int uiMessage, WPARAM wParam, LPARAM lParam);

	// For objects to register as listeners
	bool Register(const InputListener* pListener);
	// For objects to unregister as listeners
	bool Unregister(const InputListener* pListener);

	// Used bind keys to IDs
	// Returns false if the key was already bound to another ID
	bool BindKey(unsigned char ucKey, unsigned char ucID);
	// Used to unbind keys to IDs
	// Returns false if the key wasn't bound to another ID
	bool UnbindKey(unsigned char ucKey);

	// Returns the ID that a key has been bound to
	inline unsigned char GetKeyBind(unsigned char ucKey) { return m_rgucKeyBinds[ucKey]; }

	// Clean up memory
	void Shutdown(void);
};

#endif